# -*- coding: UTF-8 -*-
import PySimpleGUI as sg
import base64
import json
import os
import zipfile

upgrades_dict = {1: '☆☆☆', 0: '未升级'}
sg.ChangeLookAndFeel('Purple')
FONT = ("微软雅黑", 16)
Font_Mini = ("微软雅黑", 12)
SIZE = (20, 1)
SIZE_BTN = (8, 1)


BACKUPFILE_PATH = ''

# 算法异或与
def xorWithKey(r):
    key = b"key"
    res = bytearray()
    for i in range(len(r)):
        res.append(r[i] ^ key[i % len(key)])
    return res


# 解码
def dec(r):
    r = base64.b64decode(r)
    r = xorWithKey(r)
    return r


# 加码
def enc(r):
    r = xorWithKey(r)
    r = base64.b64encode(r)
    return r


def with_open(name, params, data=None):
    if 'w' in params:
        with open(name, params) as f:
            f.write(data)
    else:
        with open(name, params) as f:
            return f.read()


#用于DESCRIPTIONS整合成一个字符串
def listParseDes(data_list):
    for i in data_list:
        des=''
        for ii in data_list[i]['DESCRIPTIONS']:
            des=des+ii
        data_list[i]['DESCRIPTIONS'] = des
    return data_list

def reserve_key_value(data):
    return {value:key for key,value in data.items()}

# 存档备份
def backup(path):
    backupfile_path = path + '.backup'

    t = with_open(path,'rb')
    with_open(backupfile_path, 'wb', t)

    global BACKUPFILE_PATH
    BACKUPFILE_PATH = backupfile_path


#闪退回档
def recSaves():
    file_path = BACKUPFILE_PATH[:-7]
    if os.path.exists(file_path):
        os.remove(file_path)
    os.rename(BACKUPFILE_PATH, file_path)
    backup(file_path)
    

#打开存档
def openSaves(path):
    if(path):
        pass
    else:
        return
    r = dec(with_open(path, 'rb'))
    r = json.loads(r)
    return r


#写入存档，中文和英文互换就用字典选择
def writeSaves(save_data_json, values, path, all_potions_raw_data, all_cards_raw_data, all_relicses_raw_data):
    #获取输入，重新写进json、重新加码

    #------------------------角色管理------------------------------
    
    save_data_json['current_health']    = values['_current_health_']
    save_data_json['max_health']        = values['_max_health_']
    save_data_json['gold']              = values['_gold_']
    save_data_json['red']               = values['_red_']

    #------------------------药水管理------------------------------
    all_potions_name_chs2eng = {all_potions_raw_data[i]['NAME']: i for i in all_potions_raw_data}
    potion_slots = int(save_data_json['potion_slots'])
    potions =[]

    for i in range(potion_slots):
        slot = '_plot' + str(i) + '_'
        potions.append(all_potions_name_chs2eng[values[slot]])

    save_data_json['potions'] = potions

    #------------------------卡牌管理------------------------------
    #all_cards_name_chs2eng = {all_cards_raw_data[i]['NAME']: i for i in all_cards_raw_data}
    # [{'upgrades': 0, 'misc': 0, 'id': 'Strike_R'}, {'upgrades': 0, 'misc': 0, 'id': 'Strike_R'},
    # {'A Thousand Cuts': {'NAME': '凌迟', 'DESCRIPTION': '你每打出一张牌，就对所有敌人造成 !M! 点伤害。'}

    listbox_cards_name_chs = window['_cards_'].get_list_values()
    upgrades_dict_reserve = reserve_key_value(upgrades_dict)

    cards = []
    for i in listbox_cards_name_chs:
        id, upgrades = i.split('-')[3], i.split('-')[1]
        #灼热升级+5
        if id=='Searing Blow':
            cards.append({'upgrades': upgrades_dict_reserve[upgrades]+5, 'misc': 0, 'id': id})
            continue

        cards.append({'upgrades': upgrades_dict_reserve[upgrades],'misc': 0,'id': id})
    save_data_json['cards'] = cards

    # ------------------------遗物管理------------------------------
    listbox_relicses_name_chs = window['_relicses_'].get_list_values()
    relics = []
    for i in listbox_relicses_name_chs:
        name = i.split('-')[-1]
        relics.append(name)

    save_data_json['relics'] = relics

    #------------------------写入管理------------------------------
    r = json.dumps(save_data_json, indent=2, separators=(', ', ': '))
    with_open(path, 'wb', enc(bytes(r, encoding='utf-8')))


#数据预处理
def preLoading(path):
    if path == '':
        return
    jar_url = ''

    t = path.split('/')[:-2]
    for i in t:
        jar_url = jar_url + i + '/'
    jar_url = jar_url + 'desktop-1.0.jar'

    read_jar = zipfile.ZipFile(jar_url)
    
    # ----------------------------卡牌数据的处理---------------------------------
    cards = json.loads(read_jar.read('localization/zhs/cards.json'))

    
    # ----------------------------怪兽数据的处理---------------------------------
    #monsters = json.loads(read_jar.read('localization/zhs/monsters.json'))
    monsters = []
    
    # ----------------------------药水数据的处理---------------------------------
    potions_raw_data = json.loads(read_jar.read('localization/zhs/potions.json'))
    potions = listParseDes(potions_raw_data)

    # ----------------------------遗物数据的处理---------------------------------
    relics_raw_data = json.loads(read_jar.read('localization/zhs/relics.json'))
    relics = listParseDes(relics_raw_data)

    # ---------------------------所有数据的保存---------------------------------
    datas = {
        'cards':cards,
        'monsters':monsters,
        'potions':potions,
        'relics':relics,
         }
    r = json.dumps(datas, indent=2, separators=(', ', ': '))
    with_open('datas.ini', 'w', r)


#存档中各种数据的处理
def men_data_deal(save_data_json):
    window['_current_health_'].update(save_data_json['current_health'])
    window['_max_health_'].update(save_data_json['max_health'])
    window['_gold_'].update(save_data_json['gold'])
    window['_red_'].update(save_data_json['red'])


def potion_data_deal(potions, potion_slots, all_potions_name):
    for i in range(potion_slots):
        slot = '_plot' + str(i) + '_'
        window[slot].update(
            visible=True,
            value=all_potions_raw_data[potions[i]]['NAME'],
            values = all_potions_name
        )


def card_data_deal(cards, all_cards_raw_data):
    cards_listbox_list = []
    for card in cards:
        upgrades = 0
        if card["upgrades"] !=0:
            upgrades = 1
        cards_listbox_list.append(all_cards_raw_data[card['id']]['NAME'] + '-' + upgrades_dict[upgrades] + '-' + all_cards_raw_data[card['id']]['DESCRIPTION'] + '-' + card['id'])
    window['_cards_'].update(values=cards_listbox_list)


def relics_data_deal(relicses, all_relicses_raw_data):
    relicses_listbox_list = []
    for relics in relicses:
        relicses_listbox_list.append(all_relicses_raw_data[relics]['NAME'] + '-' + all_relicses_raw_data[relics]['DESCRIPTIONS'] + '-' + relics)
    window['_relicses_'].update(values=relicses_listbox_list)


def del_listbox_list_data(key):
    new_data_list = window[key].get_list_values()
    data_index = window[key].get_indexes()
    set_index = 0

    offset = 0
    for i in data_index:
        new_data_list.remove(new_data_list[i - offset])
        set_index = i - offset - 1
        offset += 1

    window[key].update(values=new_data_list, scroll_to_index=set_index)



存档管理 = [
    [
        sg.Input(enable_events=True,  visible=False, key='_openSaves_'),
        sg.FileBrowse(button_text='打开存档', size=SIZE_BTN, enable_events=True, font=FONT, target='_openSaves_', file_types=(("autosave", "*.autosave"),)),
        sg.Btn(button_text='写入存档', key='_writeSaves_', size=SIZE_BTN, font=FONT, disabled=True)
    ],
    [
        sg.Btn(button_text='闪退回档', key='_recSaves_', size=SIZE_BTN, font=FONT, disabled=True),
        sg.Btn(button_text='初始化', key='_load_', size=SIZE_BTN, font=FONT, disabled=True)
    ]
]


角色管理 = [
    [
        sg.Text(' 当前生命:', font=FONT),
        sg.Input(key='_current_health_', font=FONT, size=(10, 1))
    ],
    [
        sg.Text(' 生命上限:', font=FONT),
        sg.Input(key='_max_health_', font=FONT, size=(10, 1))
    ],
    [
        sg.Text(' 金子数量:', font=FONT),
        sg.Input(key='_gold_', font=FONT, size=(10, 1))
    ],
    [
        sg.Text(' 能量点数:', font=FONT),
        sg.Input(key='_red_', font=FONT, size=(10, 1))
    ]
]


# 常规三个，特殊五个或者两个 自适应调整
药水管理 = [
    [sg.InputCombo([], size=(18,10), font=FONT, key='_plot0_', visible=False)],
    [sg.InputCombo([], size=(18,10), font=FONT, key='_plot1_', visible=False)],
    [sg.InputCombo([], size=(18,10), font=FONT, key='_plot2_', visible=False)],
    [sg.InputCombo([], size=(18,10), font=FONT, key='_plot3_', visible=False)],
    [sg.InputCombo([], size=(18,10), font=FONT, key='_plot4_', visible=False)],
    [sg.pin(sg.Text('打开存档，进行药水管理', font=FONT, key='_potiontext_', visible=True))]
]



卡牌管理 = [
    [
        sg.Listbox([],
                   size=(28,15),
                   font=Font_Mini,
                   key='_cards_',
                   select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE,
                   horizontal_scroll=True,
                   auto_size_text=True
                   )
    ],[
        sg.Btn(button_text='删除卡牌', key='_del_card_', size=SIZE_BTN, font=FONT, disabled=True),
        sg.Btn(button_text='升级卡牌', key='_up_card_', size=SIZE_BTN, font=FONT, disabled=True)
    ]
]


遗物管理 = [
    [
        sg.Listbox([],
                   size=(28,15),
                   font=Font_Mini,
                   key='_relicses_',
                   select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE,
                   horizontal_scroll=True,
                   auto_size_text=True
                   )
    ],[
        sg.Btn(button_text='添加遗物', key='_add_relics_', size=SIZE_BTN, font=FONT, disabled=True),
        sg.Btn(button_text='删除遗物', key='_del_relics_', size=SIZE_BTN, font=FONT, disabled=True)
    ]
]

column_1 = sg.Column([
    [sg.Frame('角色管理', 角色管理, font=Font_Mini)],

    [sg.Frame('药水管理', 药水管理, font=Font_Mini)],
    [sg.Frame('存档管理', 存档管理, font=Font_Mini)],
], expand_y=True)

column_2 = sg.Column([
    [sg.Frame('卡牌管理', 卡牌管理, font=Font_Mini)]
],expand_y=True, key='_Column2_')

column_3 = sg.Column([
    [sg.Frame('遗物管理', 遗物管理, font=Font_Mini)]
],expand_y=True, key='_Column3_')


layout = [
    [column_1,column_2,column_3]
]

x, y = sg.Window.get_screen_size()
# 'GodSlayTheSpireMini'
window = sg.Window('GodSlayTheSpireMini', layout=layout, finalize=True, keep_on_top = True, location=(x*0.2, y*0.15))

# 添加卡牌扩展窗口


# 添加遗物扩展窗口

window_add_relics_active = False

while True:
    event, values = window.read(timeout=100)
    
    if event is None or event == 'Cancel':
        break

# -----------------------------打开存档事件--------------------------------------------
   
    if event == '_openSaves_':

        # --------------路径判断-----------------------
        path = values['_openSaves_']
        if path == '':
            continue

        # --------------数据备份-----------------------
        backup(path)

        # --------------数据读取-----------------------                
        if not os.path.exists('datas.ini'):
            sg.popup('您是第一次使用需要初始化！已进行初始化\n以后如有版本更新，直接点击初始化按钮即可',
                     title='初始化', keep_on_top=True)
            preLoading(path)

        # ---------本地加载缓存--------------
        cache = json.loads(with_open('datas.ini', 'r'))

        # ---------存档读取json-------------
        save_data_json = openSaves(path)

        # --------角色管理模块-----------
        men_data_deal(save_data_json)


        # --------药水管理模块-------------
        all_potions_raw_data = cache['potions']
        all_potions_name = [all_potions_raw_data[i]['NAME'] for i in all_potions_raw_data]

        potions = save_data_json['potions']
        potion_slots = int(save_data_json['potion_slots'])

        potion_data_deal(potions, potion_slots, all_potions_name)


        # --------卡牌管理模块-------------
        all_cards_raw_data = cache['cards']

        cards = save_data_json['cards']
        card_data_deal(cards, all_cards_raw_data)

        # --------遗物管理模块-------------
        all_relicses_raw_data = cache['relics']
        
        relics = save_data_json['relics']
        relics_data_deal(relics, all_relicses_raw_data)


        # --------------按钮控件更新------------
        window['_writeSaves_'].update(disabled=False)
        window['_recSaves_'].update(disabled=False)
        window['_del_card_'].update(disabled=False)
        window['_up_card_'].update(disabled=False)
        window['_add_relics_'].update(disabled=False)
        window['_del_relics_'].update(disabled=False)

        window['_potiontext_'].update(visible=False)




# -----------------------------写入存档事件--------------------------------------------
    if event == '_writeSaves_':
        
        # 数据更新、写入
        writeSaves(save_data_json, values, path, all_potions_raw_data, all_cards_raw_data, all_relicses_raw_data)
        
        # 弹窗提示、按钮禁用
        sg.popup('写入存档完成', keep_on_top=True)
        window['_writeSaves_'].update(disabled = True)
        
# -----------------------------闪退回档事件--------------------------------------------

    if event == '_recSaves_':
        recSaves()
        window['_writeSaves_'].update(disabled = True)
        window['_recSaves_'].update(disabled = True)
        sg.popup('闪退回档成功', title='闪退回档', keep_on_top=True)
        sg.popup('本修改器基于游戏内部数据源更新\n发生游戏闪退事件很可能是版本更新，请点击初始化按钮，进行重新初始化', title='初始化', keep_on_top=True)

# -----------------------------预加载事件--------------------------------------------
        
    if event == '_load_':
        path = values['_openSaves_']
        preLoading(path)
        window['_writeSaves_'].update(disabled = True)
        sg.popup('初始化完成\n请重新打开存档', title='初始化', keep_on_top=True)

# -----------------------------卡牌管理单选框--------------------------------------------
# -----------------------------卡牌管理按钮--------------------------------------------
    if event == '_del_card_':
        del_listbox_list_data(key='_cards_')

    if event == '_up_card_':
        new_cards_list = window['_cards_'].get_list_values()
        cards_index = window['_cards_'].get_indexes()
        set_index = 0


        for i in cards_index:
            new_cards_list[i] = new_cards_list[i].replace('未升级', '☆☆☆')
            set_index = i

        window['_cards_'].update(values=new_cards_list, set_to_index=set_index, scroll_to_index=set_index)

# -----------------------------遗物管理按钮--------------------------------------------
    if event == '_del_relics_':
        del_listbox_list_data(key = '_relicses_')


    if not window_add_relics_active and event == '_add_relics_':
        window_add_relics_active = True
        add_relics_layout = [
            [
                sg.Listbox(
                    [],
                    size=(60, 15),
                    font=Font_Mini,
                    key='_add_relicses_',
                    select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE,
                    horizontal_scroll=True,
                    auto_size_text=True
                )
            ], [
                sg.Btn(button_text='添加选中遗物', key='_add_choice_relics_', size=SIZE, font=FONT)
            ]
        ]
        window_add_relics = sg.Window('添加遗物',
                                      layout=add_relics_layout,
                                      finalize=True,
                                      keep_on_top=True,
                                      location=(x * 0.2, y * 0.15)
                                      )

        add_relicses_listbox_list = []

        re_relicses_data = all_relicses_raw_data
        for i in relics:
            del re_relicses_data[i]

        for relics in re_relicses_data:
            add_relicses_listbox_list.append(re_relicses_data[relics]['NAME'] + '-' + re_relicses_data[relics][
                'DESCRIPTIONS'] + '-' + relics)
        window_add_relics['_add_relicses_'].update(values=add_relicses_listbox_list)


    if window_add_relics_active:
        event_add_relics, values_add_relics = window_add_relics.read(timeout=100)
        if event_add_relics is None or event == 'Cancel':
            window_add_relics_active = False
            window_add_relics.close()
        if event_add_relics == '_add_choice_relics_':
            
            data_index = window_add_relics['_add_relicses_'].get_indexes()
            add_relics_listbox_list = window_add_relics['_add_relicses_'].get_list_values()
            set_index = 0
            offset = 0
            add_relicses_list = []

            for i in data_index:
                add_relicses_list.append(add_relics_listbox_list[i - offset])
                add_relics_listbox_list.remove(add_relics_listbox_list[i - offset])
                offset += 1

            window_add_relics['_add_relicses_'].update(values=add_relics_listbox_list)
            l = window['_relicses_'].get_list_values()
            window['_relicses_'].update(l+add_relicses_list)

            window_add_relics_active = False
            window_add_relics.close()
